from rest_framework import serializers
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from .models import UserProfile
from ctbloge.apps.comments.models import Comment
from ctbloge.apps.cms.models import Collection, Like
from rest_framework import exceptions
from django.contrib.auth import authenticate

class UserProfileSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserProfile
        fields = '__all__'
        extra_kwargs = {'password': {'write_only': True}}

    def validate_username(self, username):
        if UserProfile.objects.filter(username=username).exists():
            raise serializers.ValidationError('用户名已注册，请更换其他用户名')
        return username

    def validate_email(self, email):
        if UserProfile.objects.filter(email=email).exists():
            raise serializers.ValidationError('邮箱已注册，请更换其他邮箱')
        return email

    def create(self, validated_data):
        user = UserProfile.objects.create_user(
            username=validated_data['username'],
            email=validated_data['email'],
            password=validated_data['password'],
            phone=validated_data.get('phone', '')
        )
        return user


class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
    def validate(self, attrs):
        credentials = {
            'username': attrs.get('username'),
            'password': attrs.get('password')
        }

        # 支持邮箱/用户名混合登录
        user = self._authenticate_user(credentials)

        if not user:
            raise exceptions.AuthenticationFailed('用户不存在')
        if not user.is_active:
            raise exceptions.AuthenticationFailed('账户未激活')

        # 验证密码
        if not user.check_password(credentials['password']):
            raise exceptions.AuthenticationFailed('密码错误')

        # 获取JWT令牌
        data = super().validate(attrs)
        data['user'] = UserNicknameSerializer(user).data
        return data

    def _authenticate_user(self, credentials):
        """支持用户名/邮箱混合认证"""
        username = credentials['username']
        password = credentials['password']

        # 优先尝试邮箱登录
        if '@' in username:
            user = UserProfile.objects.filter(email=username).first()
            if user and user.check_password(password):
                return user

        # 尝试用户名登录
        user = UserProfile.objects.filter(username=username).first()
        if user and user.check_password(password):
            return user

        # 最后尝试标准认证方式
        return authenticate(
            username=username,
            password=password
        )

#获取博主信息的序列化器
class UserInfoSerializer(UserProfileSerializer):#获取博主信息的序列化器
    class Meta:
        model = UserProfile
        fields = ('id', 'username', 'email', 'nickname', 'avatar', 'bio',  'weibo', 'qq', 'qq_qrcode', 'wechat_qrcode', 'wechat_gzh_qrcode', 'github')
#获取用户昵称的序列化器
class UserNicknameSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserProfile
        fields = ('id', 'username', 'nickname','avatar')
#个人中心获取用户信息的序列化器
class UserProfileDetailSerializer(serializers.ModelSerializer):
    identity = serializers.CharField(source='get_identity_display')
    #评论数
    comment_count = serializers.SerializerMethodField()
    #点赞数
    like_count = serializers.SerializerMethodField()
    #收藏数
    collection_count = serializers.SerializerMethodField()
    created_date = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S')
    class Meta:
        model = UserProfile
        fields = ('id', 'username', 'nickname', 'avatar', 'bio', 'identity','address', 'comment_count', 'like_count', 'collection_count','created_date')
    def get_comment_count(self, obj):
        return Comment.objects.filter(author=obj).count()
    def get_like_count(self, obj):
        return Like.objects.filter(user=obj).count()
    def get_collection_count(self, obj):
        return Collection.objects.filter(user=obj).count()

#收藏文章的序列化器
class ArticleCollectionSerializer(serializers.ModelSerializer):
    article = serializers.SerializerMethodField()
    created_date = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S')

    class Meta:
        model = Collection
        fields = ['id', 'article', 'created_date']

    def get_article(self, obj):
        article = obj.content_object
        if not article:
            return None  # 处理文章被删除的情况
        return {
            'id': article.id,
            'title': article.title,
            'author': article.author.nickname,  # 根据实际字段调整
            'publish_date': article.publish_date.strftime('%Y-%m-%d %H:%M:%S'),
        }
#评论的序列化器
class CommentSerializer(serializers.ModelSerializer):
    parent_content = serializers.SerializerMethodField()
    article = serializers.SerializerMethodField()
    created_date = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S')
    class Meta:
        model = Comment
        fields = ['id', 'article', 'content', 'author','parent', 'parent_content', 'is_approved', 'created_date', 'likes_count']
    def get_parent_content(self, obj):
        if obj.parent:
            return obj.parent.content[0:35]+'...' if len(obj.parent.content)>35 else obj.parent.content
        else:
            return None
    def get_article(self, obj):
        return {
            'id': obj.article.id,
            'title': obj.article.title[0:35]+'...' if len(obj.article.title)>35 else obj.article.title,}

#修改用户基本信息的序列化器
class UserProfileUpdateSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserProfile
        fields = ('id', 'username', 'email', 'nickname', 'avatar', 'phone', 'bio')
        extra_kwargs = {
            'username': {'read_only': True},  # 根据需求设置只读字段
            'avatar': {'required': False,'allow_null':True}     # 允许不传头像
        }


#修改用户社交信息的序列化器
class UserSocialInfoUpdateSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserProfile
        fields = ('id', 'website','weibo', 'qq','wechat', 'qq_qrcode', 'wechat_qrcode', 'wechat_gzh_qrcode', 'github','gitee')

#修改用户密码的序列化器
class UserPasswordUpdateSerializer(serializers.ModelSerializer):
    old_password = serializers.CharField(write_only=True, required=True)

    class Meta:
        model = UserProfile
        fields = ('old_password', 'password')

    def validate_old_password(self, value):
        if not self.context['request'].user.check_password(value):
            raise serializers.ValidationError("旧密码验证失败")
        return value

    def update(self, instance, validated_data):
        # 密码已通过set_password处理
        return instance


#忘记密码的序列化器
class PasswordResetSerializer(serializers.Serializer):
    email = serializers.EmailField()
    code = serializers.CharField(max_length=6)
    new_password = serializers.CharField(min_length=8, max_length=20)
